home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hobby PC 15
/
Hobby PC 15.iso
/
Soft
/
Blender
/
blender.exe
/
ic255.cab
/
python
/
lwoimport.py
< prev
next >
Wrap
Text File
|
2001-03-15
|
11KB
|
330 lines
#######################
# (c) Jan Walter 2000 #
#######################
# CVS
# $Author: jan $
# $Date: 2001/02/02 15:48:53 $
# $RCSfile: lwoimport.py,v $
# $Revision: 1.4 $
# why not use the chunk module ???
import string
import struct
import Blender
LWOscale = 10
def readChunk(file):
tag = file.read(4)
data = struct.unpack(">L", file.read(4)) # big endian
length = data[0]
return tag, length
def readFace(file):
bytes = 0
numvert = struct.unpack(">H", file.read(2)) # numvert
bytes = bytes + 2
numvert = numvert[0]
verts = []
for index in xrange(numvert):
vert = struct.unpack(">H", file.read(2)) # vert
bytes = bytes + 2
verts.append(vert[0])
surf = struct.unpack(">h", file.read(2)) # surf
bytes = bytes + 2
surf = surf[0]
face = numvert, verts, surf
return face, bytes
def readFaceList(file, length):
faceList = []
numFaces = 0
bytes = 0
while bytes < length:
face, numBytes = readFace(file)
bytes = bytes + numBytes
faceList.append(face)
print "numFaces:", len(faceList)
return faceList
def readPoint(file):
return struct.unpack(">3f", file.read(12)) # big endian
def readPointList(file, length):
pointList = []
numPoints = length / 12
print "numPoints:", numPoints
for index in xrange(numPoints):
point = readPoint(file)
pointList.append(point)
return pointList
def readSurfaceDefinition(file, length):
surfaceDefinition = []
bytes = file.read(length)
words = string.split(bytes, '\0')
bytes = bytes[(len(words[0])+1):]
# skip \0
while bytes[0] == '\0':
bytes = bytes[1:]
while bytes != '':
subChunk, bytes = readSurfaceSubChunk(bytes)
surfaceDefinition.append(subChunk)
return surfaceDefinition
def readSurfaceSubChunk(bytes):
subChunk = []
tag = bytes[:4]
bytes = bytes[4:]
data = struct.unpack(">H", bytes[:2])
bytes = bytes[2:]
length = data[0]
if tag in ["COLR", "TCLR"]:
subChunk.append(tag)
r, g, b, pad = struct.unpack(">4B", bytes[:4])
bytes = bytes[4:]
subChunk.append((r, g, b))
elif tag in ["FLAG", "RFLT", "TFLG", "TFRQ"]:
subChunk.append(tag)
value = struct.unpack(">H", bytes[:2])
value = value[0]
bytes = bytes[2:]
subChunk.append(value)
elif (tag in ["LUMI", "DIFF", "SPEC", "REFL", "TRAN", "GLOS", "TVAL"] or
tag[:3] == "TIP"):
subChunk.append(tag)
value = struct.unpack(">h", bytes[:2])
value = value[0]
bytes = bytes[2:]
subChunk.append(value)
elif (tag in ["VLUM", "VDIF", "VSPC", "VRFL", "VTRN", "RSAN", "RIND",
"EDGE", "SMAN", "TAMP", "TAAS", "TOPC"] or
tag[:3] == "TFP" or tag[:3] == "TSP"):
subChunk.append(tag)
value = struct.unpack(">f", bytes[:4])
value = value[0]
bytes = bytes[4:]
subChunk.append(value)
elif tag in ["RIMG", "CTEX", "DTEX", "STEX", "RTEX", "TTEX", "LTEX",
"BTEX", "TIMG", "TALP"]:
subChunk.append(tag)
words = string.split(bytes, '\0')
filename = words[0]
bytes = bytes[(len(words[0])+1):]
# skip \0
while bytes[0] == '\0':
bytes = bytes[1:]
subChunk.append(filename)
elif tag in ["TSIZ", "TCTR", "TFAL", "TVEL"]:
subChunk.append(tag)
values = struct.unpack(">3f", bytes[:12]) # big endian
bytes = bytes[12:]
subChunk.append(values)
elif tag == "TWRP":
subChunk.append(tag)
values = struct.unpack(">HH", bytes[:4])
bytes = bytes[4:]
subChunk.append(values)
else:
bytes = bytes[length:]
return subChunk, bytes
def readSurfaceList(file, length):
bytes = file.read(length)
words = string.split(bytes, '\0')
surfaceList = []
for word in words:
if word:
surfaceList.append(word)
return surfaceList
def checkForOneLoop(indices):
for i in xrange(len(indices) - 1):
if indices.count(indices[i]) > 1:
return 0
## if indices[i] in (indices[0:i] + indices[(i+1):]):
## return 0
return 1
def testLwoImport(filename):
global LWOscale
print 'testLwoImport("%s")' % filename
file = open(filename, "rb")
tag, length = readChunk(file)
if tag == "FORM":
lwob = file.read(4)
if lwob == "LWOB":
print '"LightWave 3D Object File Format" found'
filelength = length
numBytes = 4
while (numBytes < filelength):
tag, length = readChunk(file)
numBytes = numBytes + 8
if length % 2 != 0:
length = length + 1
# surface list
if tag == "SRFS":
surfaceList = readSurfaceList(file, length)
# point list
elif tag == "PNTS":
pointList = readPointList(file, length)
# face list
elif tag == "POLS":
faceList = readFaceList(file, length)
# surface definition
elif tag == "SURF":
surfaceDefinition = readSurfaceDefinition(file, length)
else:
file.read(length)
numBytes = numBytes + length
else:
print 'No "LightWave 3D Object File Format" found :-['
return
file.close()
# import in Blender
print "import into Blender ..."
scene = Blender.getCurrentScene()
print "triangles and quads ..."
for materialIndex in xrange(1, len(surfaceList) + 1):
mesh = Blender.Mesh("LWO")
object = Blender.Object("LWO")
for face in faceList:
numvert, vert, surf = face
if surf == materialIndex:
if numvert == 3:
# triangle
mesh.enterEditMode()
indices = []
for vertex in vert:
x, y, z = pointList[vertex]
x = x * LWOscale
y = y * LWOscale
z = z * LWOscale
index = mesh.addVertex(x, y, z, 0, 0, 0)
indices.append(index)
mesh.addFace(indices[0], indices[1], indices[2], 0, 0, 0)
elif numvert == 4:
# quad
mesh.enterEditMode()
indices = []
for vertex in vert:
x, y, z = pointList[vertex]
x = x * LWOscale
y = y * LWOscale
z = z * LWOscale
index = mesh.addVertex(x, y, z, 0, 0, 0)
indices.append(index)
mesh.addFace(indices[0], indices[1],
indices[2], indices[3], 0, 0)
Blender.connect(object, mesh)
Blender.connect(scene, object)
mesh.leaveEditMode()
print "all other (general) polygons ..."
for face in faceList:
numvert, vert, surf = face
# one polygon
if numvert != 3 and numvert != 4:
mesh = Blender.Mesh("LWO")
object = Blender.Object("LWO")
hasOneLoop = checkForOneLoop(vert)
mesh.enterEditMode()
for i in xrange(len(vert)-1):
if vert.count(vert[i]) == 2:
first = vert.index(vert[i])
remaining = vert[0:first] + vert[(first+1):]
second = remaining.index(vert[i]) + 1
if i == first and vert[first+1] == vert[second-1]:
# print "ignore first edge"
pass
elif i == second and vert[first-1] == vert[second+1]:
# print "ignore second edge"
pass
else:
# print "edge not ignored"
x, y, z = pointList[vert[i]]
x = x * LWOscale
y = y * LWOscale
z = z * LWOscale
index1 = mesh.addVertex(x, y, z, 0, 0, 0)
x, y, z = pointList[vert[i+1]]
x = x * LWOscale
y = y * LWOscale
z = z * LWOscale
index2 = mesh.addVertex(x, y, z, 0, 0, 0)
mesh.addFace(index1, index2, 0, 0, 0, 0)
elif vert.count(vert[i]) > 2:
print ("vert.count(vert[%s]) = %s" %
(i, vert.count(vert[i])))
else:
x, y, z = pointList[vert[i]]
x = x * LWOscale
y = y * LWOscale
z = z * LWOscale
index1 = mesh.addVertex(x, y, z, 0, 0, 0)
x, y, z = pointList[vert[i+1]]
x = x * LWOscale
y = y * LWOscale
z = z * LWOscale
index2 = mesh.addVertex(x, y, z, 0, 0, 0)
mesh.addFace(index1, index2, 0, 0, 0, 0)
# add edge from last point to the first point to
# close the polygon
if vert.count(vert[-1]) == 2:
first = vert.index(vert[-1])
second = -1
if vert[first-1] == vert[second+1]:
# print "ignore second edge"
pass
else:
x, y, z = pointList[vert[0]]
x = x * LWOscale
y = y * LWOscale
z = z * LWOscale
index1 = mesh.addVertex(x, y, z, 0, 0, 0)
x, y, z = pointList[vert[-1]]
x = x * LWOscale
y = y * LWOscale
z = z * LWOscale
index2 = mesh.addVertex(x, y, z, 0, 0, 0)
mesh.addFace(index1, index2, 0, 0, 0, 0)
else:
x, y, z = pointList[vert[0]]
x = x * LWOscale
y = y * LWOscale
z = z * LWOscale
index1 = mesh.addVertex(x, y, z, 0, 0, 0)
x, y, z = pointList[vert[-1]]
x = x * LWOscale
y = y * LWOscale
z = z * LWOscale
index2 = mesh.addVertex(x, y, z, 0, 0, 0)
mesh.addFace(index1, index2, 0, 0, 0, 0)
# remove doubles and triangulate
if hasOneLoop:
# polygon without subloops
mesh.createTrianglesFromEdges()
else:
# polygon with subloops
mesh.createTrianglesFromEdges()
# now connect ...
Blender.connect(object, mesh)
Blender.connect(scene, object)
mesh.leaveEditMode()
print "... finished"
def callback(fs):
filename = fs.filename
testLwoImport(filename)
if __name__ == "__main__":
try:
import GUI
except:
print "This script is only working with the new GUI module ..."
else:
fs = GUI.FileSelector()
fs.activate(callback, fs)